#ifndef _BMESSAGE_HEADER_
#define _BMESSAGE_HEADER_
#include "BlueBerry.h"
#include <list>
#include <string>

enum BETypeId
{
	e_Integer = 0,
	e_Short,
	e_UnsingedInteger,
	e_UnsignedShort,
	e_Float,
	e_Double,
	e_Bool,
	e_String,
	e_Date,
	e_Time,
	e_Char,
	e_Null,

	B_TYPES_COUNT
};

enum BEFieldType
{
	e_FTMessageType = 0, e_FTErrorId,

	E_FIELD_COUNT
};

enum BEMessageType
{
	e_MTPulse = 0, e_MTError,

	E_MESSAGE_TYPES_COUNT
};

class BField //This is an abstract class which will be the interface for all the types
{
public:
	BField(BETypeId _rType, BEFieldType _etFieldId);
	inline BETypeId getTypeId() const
	{
		return et_Type;
	}
	inline BEFieldType getFieldId() const
	{
		return et_FieldId;
	}
	inline Byte getFieldLen() const
	{
		return bt_FieldLen;
	}
	virtual UInt getStreamBuffer(char * _zStream) = 0;
	virtual ~BField();
protected:
	Byte bt_FieldLen;
private:
	BETypeId et_Type;
	BEFieldType et_FieldId;

};

class BInteger: public BField
{
public:
	BInteger(BEFieldType _etFieldId, int _iValue);
	UInt getStreamBuffer(char * _zStream);
	~BInteger();
private:
	int i_Value;
};

typedef std::list<BField*> T_LST_FIELDS;
class BMessage
{
public:
	BMessage(BEMessageType _etMessageType, BMessage * _pParent = NULL);
	~BMessage();
	void setField(BEFieldType _etFieldType, BField * _pField);
	BField * getField(BEFieldType _etFieldType);
	void removeField(BEFieldType _etFieldType);
	UInt getStreamBuffer(char * _zStream);
	void setChild(BMessage * _pChild)
	{
		p_Child = _pChild;
	}
	void setParent(BMessage * _pParent)
	{
		p_Parent = _pParent;
	}
	inline BMessage * getChild()
	{
		return p_Child;
	}
	inline BMessage * getParent()
	{
		return p_Parent;
	}
	void clear();
	void clearChildren();
private:
	BField * ap_Fields[E_FIELD_COUNT];
	T_LST_FIELDS lst_StoredFields;
	UInt ui_MessageLen;
	BMessage * p_Child, *p_Parent;
};

class BShort: public BField
{
public:
	BShort(short s_Value);
	UInt getStreamBuffer(char * _zStream);
private:
	short s_Value;
};

class BUnsingedInteger: public BField
{
public:
	BUnsingedInteger(unsigned int _uiValue);
	UInt getStreamBuffer(char * _zStream);
private:
	unsigned int ui_Value;
};

class BUnsignedShort: public BField
{
public:
	BUnsignedShort(unsigned short _us_Value);
	UInt getStreamBuffer(char * _zStream);
private:
	unsigned short us_Vlaue;
};

class BFloat: public BField
{
public:
	BFloat(float _fValue);
	UInt getStreamBuffer(char * _zStream);
private:
	float f_Value;
};

class BDouble: public BField
{
public:
	BDouble(double _dValue);
	UInt getStreamBuffer(char * _zStream);
private:
	double d_Value;
};

class BBool: public BField
{
public:
	BBool(bool _bValue);
	UInt getStreamBuffer(char * _zStream); //Changed by Eran from Uint to UInt
private:
	bool b_Value;
};

class BChar: public BField
{
public:
	BChar(char _cValue);
	UInt getStreamBuffer(char * _zStream);
private:
	char c_Value;
};

class BString: public BField
{
public:
	BString(string _sValue);
	UInt getStreamBuffer(char * _zStream);
private:
	string s_value;
};

class BNull
{
public:
	BNull();
	UInt getStreamBuffer(char * _zStream);//Changed by Eran from UInit to UInt
};

class BDate: public BField
{
public:
	BDate(unsigned short _dValue, unsigned short _mValue,
			unsigned short _yValue);
private:
	unsigned short d_Value, m_Value, y_Value;

};

class BTime: public BField
{
public:
	BTime(unsigned short _hValue, unsigned short _mValue,
			unsigned short _sValue);
	UInt getStreamBuffer(char * _zStream);
private:
	unsigned short h_Value, m_Value, s_Value;
};

#endif//_BMESSAGE_HEADER_
